zhouqijie

一、光源

环境光(Ambient):

最简单的光源,没有光源位置。无论对象在何处,其上的每个像素都有相同的光照。

float globalAmbient[4] = {0.6f, 0.,6f, 0.6f, 1.0f};

定向光(Directional light):

定向光也没有光源位置,但是具有方向。
定向光用于模拟光源位置很远以至于光线接近平行的情况。(例如太阳)

点光源(point light):

又称位置光,在场景中有特定位置。但对于场景中每个点的光照方向都不同。

点光源有衰减因子,衰减因子有很多建模方式。最常用建模方式:factor = 1 / (k1 + k2*d + k3*d*d)

※聚光灯(spot light):

限制了方向范围的点光源。

二、光照模型

光照模型(Lighting model)也称为着色模型(Shading model),有时也称为反射模型(Reflection model)。

最常见的光照模型是标准光照模型。(一种ADS光照模型)

其他的复杂光照模型有基于物理的渲染(PBR)的BRDF光照模型等。

三、标准光照模型(Blinn-Phong模型)

三部分:

  1. Ambient环境光:
    全局变量。

  2. Diffuse漫反射:
    lambert模型。

  3. Specular高光反射:
    Phong模型和Blinn模型。

公式:

$I_{observed} = I_{ambient} + I_{diffuse} + I_{specular}$


逐像素和逐顶点光照:


Blinn-Phong着色:

Blinn在Phong着色上引入了角平分向量H,取代了反射向量R的计算。(Phong着色中反射向量R的计算消耗很大)

角平分向量H的计算在片段着色器或者顶点着色器中进行都可以。


Blinn-Phong着色器代码:

//顶点着色器代码:
#version 430

struct DirectionalLight
{
	vec4 color;
	vec3 dir;
};

struct Material
{
	vec4 diffuse;
	vec4 specular;
	float gloss;
};

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texcoords;
layout (location = 2) in vec3 normal;

uniform mat4 m_matrix;
uniform mat4 v_matrix;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 norm_matrix;

uniform vec4 ambient;
uniform DirectionalLight light;
uniform Material material;

//layout(binding = 0) uniform sampler2D samp;

out vec3 varyingPos;
out vec3 varyingNormal;
out vec2 uv;

void main(void)
{ 
	varyingPos = (mv_matrix * vec4(position, 1.0)).xyz;
	varyingNormal = (norm_matrix * vec4(normal, 1.0)).xyz;
	uv = texcoords;
	gl_Position = proj_matrix * mv_matrix * vec4(position, 1.0);
}
//片段着色器代码:
#version 430
struct DirectionalLight
{
	vec4 color;
	vec3 dir;
};

struct Material
{
	vec4 diffuse;
	vec4 specular;
	float gloss;
};


in vec3 varyingPos;
in vec3 varyingNormal;
in vec2 uv;

out vec4 color;


uniform mat4 m_matrix;
uniform mat4 v_matrix;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 norm_matrix;

uniform vec4 ambient;
uniform DirectionalLight light;
uniform Material material;

layout(binding = 0) uniform sampler2D samp;

void main(void)
{
	vec3 N = normalize(varyingNormal);
	vec3 L = normalize((v_matrix * vec4(-light.dir, 0.0)).xyz);
	vec3 V = normalize(-varyingPos);
	vec3 H = normalize(L + V);

	vec3 diffuse = light.color.xyz * material.diffuse.xyz * max(0.0, dot(N, L));
	vec3 specular = light.color.xyz * material.specular.xyz * pow(max(0.0, dot(H, N)), material.gloss); 


	color = texture(samp, uv) * vec4((ambient.xyz + diffuse + specular), 1.0); 
}